package com.spark.quartz.utils;

import com.spark.common.utils.SpringUtils;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * 任务执行工具
 *
 * @author LYCHEE
 * @date 2025/4/3 09:47
 */
public class JobInvokeUtil {

    /**
     * 调用目标方法
     *
     * @param invokeTarget 格式示例：xxxx.spParams('ry', 123, 3.14, true)
     */
    public static void invokeMethod(String invokeTarget) throws Exception {
        // 1. 拆分方法名和参数部分
        String methodPart = invokeTarget.split("\\(")[0];
        String paramPart = invokeTarget.contains("(")
                ? invokeTarget.split("\\(")[1].replace(")", "").trim()
                : "";
        // 2. 判断调用类型：Bean调用 或 Class类调用
        boolean isBeanCall = isBeanCall(methodPart);

        // 3. 解析类/Bean名称、方法名
        String[] parts = methodPart.split("\\.");
        if (parts.length < 2) {
            throw new IllegalArgumentException("方法格式错误：" + invokeTarget);
        }

        String targetName = isBeanCall ? parts[0] : String.join(".", Arrays.copyOf(parts, parts.length - 1));
        String methodName = parts[parts.length - 1];

        // 4. 获取目标对象（Bean 或 Class实例）
        Object target;
        if (isBeanCall) {
            // 从Spring容器获取Bean
            target = SpringUtils.getBean(targetName);
        } else {
            // 反射创建类实例
            Class<?> clazz = Class.forName(targetName);
            target = clazz.getDeclaredConstructor().newInstance();
        }

        // 5. 处理参数
        Object[] params = parseParams(paramPart);
        Class<?>[] paramTypes = getParamTypes(params);

        // 6. 反射调用方法
        Method method = target.getClass().getDeclaredMethod(methodName, paramTypes);
        method.invoke(target, params);
    }

    /**
     * 判断是否为Bean调用（规则：如果第一个段不是包名，则为Bean调用）
     */
    private static boolean isBeanCall(String methodPart) {
        String[] parts = methodPart.split("\\.");
        // 简单规则：如果首字母小写且不包含大写包名，则视为Bean调用
        return Character.isLowerCase(parts[0].charAt(0)) && parts.length == 2;
    }

    /**
     * 解析参数字符串（支持空参数）
     */
    private static Object[] parseParams(String paramStr) {
        if (paramStr == null || paramStr.isEmpty()) {
            return new Object[0];
        }
        String[] paramArr = paramStr.split(",\\s*");
        return Arrays.stream(paramArr)
                .map(param -> {
                    // 处理字符串（单引号包裹）
                    if (param.startsWith("'") && param.endsWith("'")) {
                        return param.substring(1, param.length() - 1);
                    }
                    // 处理布尔值
                    if (param.equalsIgnoreCase("true")) {
                        return true;
                    }
                    if (param.equalsIgnoreCase("false")) {
                        return false;
                    }
                    // 处理 Long 类型（以 L/l 结尾）
                    if (param.matches(".*[Ll]$")) {
                        String number = param.replaceAll("[Ll]$", "");
                        try {
                            return Long.parseLong(number);
                        } catch (NumberFormatException e) {
                            throw new IllegalArgumentException("无效的长整型参数: " + param);
                        }
                    }
                    // 处理 Double 类型（以 D/d 结尾或包含小数点）
                    if (param.matches(".*[Dd]$")) {
                        String number = param.replaceAll("[Dd]$", "");
                        try {
                            return Double.parseDouble(number);
                        } catch (NumberFormatException e) {
                            throw new IllegalArgumentException("无效的浮点数参数: " + param);
                        }
                    }
                    if (param.contains(".")) {
                        try {
                            return Double.parseDouble(param);
                        } catch (NumberFormatException e) {
                            throw new IllegalArgumentException("无效的浮点数参数: " + param);
                        }
                    }
                    // 处理整型（优先解析为 Integer，超出范围则转为 Long）
                    try {
                        return Integer.parseInt(param);
                    } catch (NumberFormatException e) {
                        try {
                            return Long.parseLong(param);
                        } catch (NumberFormatException ex) {
                            throw new IllegalArgumentException("无效的整数参数: " + param);
                        }
                    }
                })
                .toArray();
    }

    /**
     * 获取参数类型数组（空参数返回空数组）
     */
    private static Class<?>[] getParamTypes(Object[] params) {
        return Arrays.stream(params)
                .map(Object::getClass)
                .toArray(Class<?>[]::new);
    }
}
